﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AppDateService.Contract;
using AppDateService.Contract.Request;
using AppDateService.Contract.Response;
using AppDateService.Model;
using System.Configuration;

namespace AppDateService.Common
{
    public class SessionUtils
    {
        public static readonly double SESSION_TIMEOUT = double.Parse(ConfigurationManager.AppSettings["sessionTimeout"]);
        private AppDateEntities _context = new AppDateEntities();
        
        /// <summary>
        /// Only use for login
        /// </summary>
        /// <param name="user"></param>
        /// <param name="nonce"></param>
        /// <returns></returns>
        public Session CreateSession(CUser user)
        {
            Session session = _context.Sessions.SingleOrDefault(p => p.UserID == user.ID);
            if (session == null)
            {
                session = _context.Sessions.CreateObject();
                session.UserID = user.ID;
                session.Token = Utils.CreateMD5Hash(user.ID + DateTime.Now.ToString("yyyyMMddHHmmssffff"));
                session.Nonce = Utils.CreateMD5Hash(DateTime.Now.ToString("yyyyMMddHHmmssffff"));                
                session.Expired = DateTime.Now.AddMinutes(SESSION_TIMEOUT);
                session.IsAuthenticated = true;
                _context.Sessions.AddObject(session);
                _context.SaveChanges();
            }
            else
            {
                //Check nonce successful then update neccessary info
                session.Nonce = Utils.CreateMD5Hash(DateTime.Now.ToString("yyyyMMddHHmmssffff"));
                session.Expired = DateTime.Now.AddMinutes(SESSION_TIMEOUT); //extra session timeout
                session.IsAuthenticated = true;
                _context.SaveChanges();
            }

            return session;
        }

        public Session CheckSessionTimeout(string token, string nonce, out ResponseStatus status,bool notRegenNonce = false)
        {
            Session session = _context.Sessions.SingleOrDefault(p => p.Token == token && p.Nonce == nonce);
            if (session != null)
            {
                if (session.IsAuthenticated)
                {
                    //Check Expired
                    if (session.Expired.CompareTo(DateTime.Now) > 0)//Session is not expired
                    {
                        //Check nonce successful then update neccessary info
                        if (session.Nonce.Equals(nonce))
                        {
                            if (!notRegenNonce)
                            {
                                //Generate new nonce
                                session.Nonce = Utils.CreateMD5Hash(DateTime.Now.ToString("yyyyMMddHHmmssffff"));
                            }
                            //extra session timeout
                            session.Expired = DateTime.Now.AddMinutes(SESSION_TIMEOUT);
                            status = ResponseStatus.Success;
                        }
                        else //Check nonce failed
                        {
                            session.IsAuthenticated = false;
                            status = ResponseStatus.Error;
                        }
                    }
                    else
                    {
                        session.IsAuthenticated = false;
                        status = ResponseStatus.SessionTimeout;
                    }
                    _context.SaveChanges();
                }
                else
                {
                    status = ResponseStatus.Unanthenticated;
                }
            }
            else
            {
                status = ResponseStatus.Unanthenticated;
            }

            return session;
        }
    }
}